<template>
  <base-panel :show.sync="visible" :width="panelWidth" :newStyle="true">
    <h3 slot="title">
      <span>{{$t('component.advancedSearch.title')}}</span>
      <el-dropdown
        class="pull-right"
        trigger="click"
        @command="setAdvanceSearchColumn"
      >
        <i
          class="iconfont icon-xitongguanli customer-panel-btn"
          style="float: none;"
        ></i>

        <el-dropdown-menu slot="dropdown" class="customer-advance-setting">
          <el-dropdown-item command="1">{{$t('common.base.table.oneCl')}}</el-dropdown-item>
          <el-dropdown-item command="2">{{$t('common.base.table.twoCl')}}</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </h3>
    <el-form label-position="top" class="advanced-search-form" onsubmit="return false;">
      <search-form
        v-show="show"
        :fields="fields"
        ref="searchForm"
        :form-backup="formBackup"
        :column-num="columnNum"
      ></search-form>
      <slot name="footer"></slot>
    </el-form>

  </base-panel>
</template>

<script>
import {
  FormFieldMap,
  SettingComponents,
} from "@src/component/form/components";
// import {PRODUCT_SEARCH_MODAL_COM_DATA, PRODICT_LIST_SEARCHPANEL_LOCALSTORAGE} from "@src/modules/productV2/storage"
import * as Utils from "@src/component/form/util";
import { getTimestamp } from 'pub-bbx-utils';
import _ from "lodash";
import { isEmptyStringObject } from "@src/util/function";

import { isFunction } from '@src/util/type'
import LabelSearch from './LabelSearch'
import { safeNewDate } from '@src/util/time';
import { cloneData } from "@src/api/ProductV2Api";

import { formatAddress } from 'pub-bbx-utils';
import { baseDistValueToObject, searchAddressObjectParams } from '@src/util/addressUtil';
export default {
  name: "search-panel",
  props: {
    config: {
      type: Object,
      default: () => ({}),
    },
    type:{
      type: Number,
      default: null
    }
  },
  data() {
    return {
      visible: false,
      formBackup: {},
      columnNum: 1,
      selfFields: [],
      show: true,
      diyFields: [],
      CloneData: [],
      CloneDataMap: new Map(),
    };
  },
  watch: {
    visible(newValue) {
      this.$emit('visibleChange', newValue)
    },
    type:{
      immediate:true,
      handler(){
        this.buildSelfFields()
      }
    }
  },
  computed: {
    fields() {
      let f = {};
      let fields = [...this.config.fields, ...this.selfFields]
        .filter((f) => f.isSearch || f.isSystem )
        .map((field) => {
          f = _.cloneDeep(field);

          let formType = f.formType;

          if (formType === "datetime") {
            formType = "date";
          }

          if (formType === "updateTime") {
            f.displayName = this.$t('common.base.column.updateTime');
          }

          return Object.freeze({
            ...f,
            isNull: 1,
            formType,
            originalFormType: f.formType,
            operator: this.matchOperator(f),
          });
        })
        .sort((a, b) => a.orderId - b.orderId);
      // let obj_ = storageGet(PRODUCT_SEARCH_MODAL_COM_DATA);
      // if (obj_) {
      //   obj_ = JSON.parse(obj_);
      //   if (obj_.allCheckList.length) {
      //     this.diyFields = fields.filter(
      //       (item) => obj_.allCheckList.indexOf(item.fieldName) > -1
      //     );
      //   }
      // }
      // this.diyFields = fields

      return fields;
    },
    panelWidth() {
      return `${502 * this.columnNum}px`;
    },
  },
  mounted() {
    // const { column_number } = this.getLocalStorageData();
    // if (column_number) this.columnNum = Number(column_number);

    this.GetCloneData()
  },
  methods: {
    // 获取产品类型
    GetCloneData(){
       cloneData().then((res) => {
        if (res.code !== 0) {
          this.$message.error(res.message);
          return;
        }

        let { result } = res;
        this.deleteEmpty(result);

        // 产品类型 数据处理
      this.CloneData = result

      const DeepResult = (node,Parent=null)=>{
        if(node.conData === 1){
           this.CloneDataMap.set(node.id,{...node})
        }
        if(node?.tasks?.length){
          for(let item of node.tasks){
            DeepResult(item,node)
          }
        }
      }
      for(let item of this.CloneData){
        DeepResult(item)
      }


       })
    },
    async buildSelfFields() {
      let fields = [
        {
          displayName: this.$t('common.base.column.createPerson'),
          fieldName: 'createUser',
          formType: 'user',
          isExport: false,
          isNull: 1,
          isSystem: 1,
          orderId: 12
        },
        {
          displayName: this.$t('common.base.column.lastUpdatePerson'),
          fieldName: 'updateUser',
          formType: 'user',
          isExport: false,
          isNull: 1,
          isSystem: 1,
          orderId: 12
        },
        {
          displayName: this.$t('common.base.column.createTime'),
          fieldName: "createTime",
          formType: "date",
          export: false,
          isNull: 1,
          isSystem: 1,
          operator: "between",
          orderId: -2,
        },
        {
          displayName: this.$t('common.base.column.updateTime'),
          fieldName: 'updateTime',
          formType: 'datetime',
          isExport: false,
          isNull: 1,
          isSystem: 1,
          operator: 'between',
          orderId: 13
        },
        {
          displayName: '编号',
          fieldName: 'wikiNumber',
          formType: 'text',
          isExport: false,
          isNull: 1,
          isSystem: 1,
          orderId: 16
        },
        {
          displayName: this.$t('common.base.column.div'),
          fieldName: 'label',
          formType: 'label',
          isExport: false,
          isNull: 1,
          isSystem: 1,
          operator: 'between',
          orderId: 14
        },
      ];

      if(this.type === 1){
        // 故障库列表，显示产品类型筛选
        fields.push({
            displayName: this.$t('common.base.column.productType'),
            fieldName: "productTypeList",
            formType: "cascader",
            isExport: false,
            isNull: 1,
            isSystem: 1,
            operator: "between",
            orderId: 15,
            version: "new",
            tree: this.CloneData ? this.CloneData : [],
            collapseTags: true,
            showAllLevels: true,
            propsV2: {
              multiple: true,
              value: "id",
              label: "name",
              children: "tasks",
              expandTrigger: "hover",
            },
          })
      }


      this.selfFields = fields;
      this.computedWhetherAddQrcodeField()
    },
    // 删除空子集
    deleteEmpty(list) {
      list.forEach((item) => {
        if (!item.tasks.length) {
          delete item.tasks;
        } else {
          this.deleteEmpty(item.tasks);
        }
      });
    },
    computedWhetherAddQrcodeField() {
      this.selfFields = [
        ...this.selfFields
      ];
    },
    // saveDataToStorage(key, value) {
    //   const data = this.getLocalStorageData();
    //   data[key] = value;
    //   localStorage.setItem(
    //     PRODICT_LIST_SEARCHPANEL_LOCALSTORAGE,
    //     JSON.stringify(data)
    //   );
    // },
    // getLocalStorageData() {
    //   const dataStr = localStorage.getItem(PRODICT_LIST_SEARCHPANEL_LOCALSTORAGE) || "{}";
    //   return JSON.parse(dataStr);
    // },
    matchOperator(field) {
      let formType = field.formType;
      let operator = "";

      switch (formType) {
      case "date": {
        operator = "between";
        break;
      }
      case "datetime": {
        operator = "between";
        break;
      }
      case "select": {
        if (field.setting && field.setting.isMulti) {
          operator = "contain";
        } else {
          operator = "eq";
        }
        break;
      }
      case "cascader": {
        operator = "cascader";
        break;
      }
      case "user": {
        operator = "user";
        break;
      }
      case "address": {
        operator = "address";
        break;
      }
      case "location": {
        operator = "location";
        break;
      }
      case "related_task": {
        operator = "array_eq";
        break;
      }
      case "formula": {
        operator = "eq";
        break;
      }
      default: {
        operator = "like";
        break;
      }
      }
      return operator;
    },
    resetParams() {
      this.formBackup = {};
      this.$refs.searchForm
        && this.$nextTick(this.$refs.searchForm.initFormVal);
    },

    buildParams() {
      let form
      try {
        form = this.$refs.searchForm.returnData();
      } catch (error) {
        console.warn(error, "error try catch");
      }
      this.formBackup = Object.assign({}, form);

      const isSystemFields = this.fields.filter((f) => f.isSystem);
      const notSystemFields = this.fields.filter((f) => !f.isSystem);
      let params = {
        conditions: [],
      };

      let tv = null;
      let fn = "";

      for (let i = 0; i < isSystemFields.length; i++) {
        tv = isSystemFields[i];
        fn = tv.fieldName;

        // hasRemind
        if (fn === "hasRemind" && form[fn] !== "") {
          params.hasRemind = form[fn] == 2 ? 0 : form[fn];
          continue;
        }

        if (fn === "qrcodeState" && form[fn] !== "") {
          params.qrcodeState = form[fn] == 2 ? 0 : form[fn];
          continue;
        }

        if (fn === "productTypeList" && form[fn]?.length){
          // 数据扁平化 去重
          let list = form.productTypeList.flat(Infinity)
          list = list.filter((value,index,Arr)=>{
            return Arr.findIndex((v,i)=>v === value) === index
          })
          params.productTypeList = list?.map(item=>{
            let info = this.CloneDataMap.get(item)
            if(info){
              return {
                name:info.name,
                id:info.id,
              }
            }
          })
          params.productTypeList= params.productTypeList.filter(item=>!!item)
        }

        if (fn == "area") {
          const address = baseDistValueToObject(form[fn])
          params.productAddress = {
            ...(params.productAddress || {}),
            ...(searchAddressObjectParams(address))
          };
          continue;
        }

        if (fn === "addressDetail") {
          params.productAddress = {
            ...(params.productAddress || {}),
            address: form[fn],
          };
          continue;
        }

        // if (!form[fn] || (Array.isArray(form[fn]) && !form[fn].length)) {
        //   continue;
        // }

        if(['date', 'datetime'].includes(tv.formType)){
          // *注意：这里没有时间也要传递undefined, 业务中使用了Object.assign(this.params, params)
          // *如果不传递undefined, 会导致时间保留了上一次的值
          const [start, end ] = form[fn] || []
          const startKey = `${fn}Start`;
          const endKey = `${fn}End`;
          params[startKey] = getTimestamp(start);
          params[endKey] = getTimestamp(end);
          continue;
        }

        if (tv.formType === "tags") {
          params.tagId = form[fn].map(({ id }) => id).join("");
        }

        if (typeof form[fn] === "string") {
          params[fn === "customer" ? "customerId" : fn] = form[fn];
          continue;
        }

        if (typeof form[fn] === "number") {
          params[fn] = form[fn];
          continue;
        }


      }

      for (let i = 0; i < notSystemFields.length; i++) {
        let key = null;
        tv = notSystemFields[i];
        fn = tv.fieldName;

        if (!form[fn] || (Array.isArray(form[fn]) && !form[fn].length)) {
          continue;
        }

        // 空对象
        if (
          typeof form[fn] === "object"
          && !Array.isArray(form[fn])
          && !Object.keys(form[fn]).length
        ) {
          continue;
        }

        if(['date', 'datetime'].includes(tv.originalFormType)){
          params.conditions.push({
            property: fn,
            operator: tv.operator,
            betweenValue1: form[fn][0],
            betweenValue2: form[fn][1],
          });
          continue;
        }

        if (tv.formType === "cascader") {
          params.conditions.push({
            property: fn,
            operator: tv.operator,
            inValue: form[fn],
          });
          continue;
        }

        if (tv.formType === "address") {
          let address = {
            property: fn,
            operator: tv.operator,
          };
          let isEmpty = isEmptyStringObject(form[fn]);

          if (!isEmpty) {
            address.value = formatAddress(form[fn],'');
          }
          params.conditions.push(address);
          continue;
        }

        if (tv.originalFormType === "related_task") {
          key = "taskNo";
        }

        params.conditions.push({
          property: fn,
          operator: tv.operator,
          value: form[fn],
          key,
        });
      }
      return params;
    },
    setAdvanceSearchColumn(command) {
      this.columnNum = Number(command);
      // this.saveDataToStorage("column_number", command);
    },
    open() {
      this.visible = true;
    },
  },
  components: {
    SearchForm: {
      name: "search-form",
      props: {
        fields: {
          type: Array,
          default: () => [],
        },
        formBackup: {
          type: Object,
          default: () => ({}),
        },
        columnNum: {
          type: Number,
          default: 1,
        },
      },
      data() {
        return {
          form: {},
          tableName: "product",
          show: true,
        };
      },
      mounted() {
        this.buildForm();
      },
      methods: {
        returnData() {
          return Object.assign({}, this.form);
        },
        buildForm() {
          if (Object.keys(this.form).length === this.fields.length) return;
          this.initFormVal();
        },
        initFormVal() {
          let fields = this.fields;
          let form = {};
          let tv = "";

          fields.forEach((field) => {
            tv = "";
            // 地址的默认值初始化为对象
            if (
              field.formType == "customerAddress"
              || field.formType == "address"
            )
              tv = {};
            if (field.formType == "date" || field.formType == "datetime")
              tv = [];
            if (field.formType === "link") {
              tv = {};
            }
            if (field.formType === "tags") {
              tv = [];
            }
            if (field.formType === "area") {
              tv = [];
            }
            if (field.formType === "cascader") {
              tv = [];
            }
            if (field.formType === "label") {
              tv = '';
            }
            form[field.fieldName] = this.formBackup[field.fieldName] || tv;

            this.$set(
              this.form,
              field.fieldName,
              this.formBackup[field.fieldName] || tv
            );
          });

          return form;
        },
        update(event, action) {
          
          if (action === "tags") {
            return this.$set(this.form, "tags", event);
          }

          if (action === "dist") {
            return this.$set(this.form, "area", event);
          }
          
          const field = event.field
          if (field.returnData){
            event.newValue = (
              isFunction(field.returnData) 
                ? field.returnData(event.newValue) 
                : event.newValue[field.returnData] || event.newValue
            )
          }

          this.$set(this.form, field.fieldName, event.newValue);
        },
        createUserInput(event, isTags) {
          if (isTags) {
            return (this.form.tags = event);
          }
          const f = event.field;
          this.form[f.fieldName] = event.keyword;
        },
        renderInput(h, field) {
          const f = {
            ...Object.freeze(field),
          };

          let comp = FormFieldMap.get(f.formType);

          if (
            !comp
            && f.formType !== "label"
          ) {
            return null;
          }

          if (f.formType === "select") {
            f.setting.isMulti = false;
          }

          let childComp = null;

          if (f.formType === "user") {
            childComp = h("user-search", {
              props: {
                field: f,
                value: this.form[f.fieldName],
                disableMap: true,
              },
              on: {
                update: (event) => this.update(event),
                input: (event) => {
                  this.form[f.fieldName] = event.keyword;
                },
              },
            });
          } else if (f.formType === 'label') {
            childComp = h(
              'label-search',
              {
                props: {
                  field: f,
                  value: this.form[f.fieldName],
                  disableMap: true,
                },
                on: {
                  update: event => this.update(event)
                }
              });
          } else {
            childComp = h(
              comp.extend && comp.extend[`${f.formType}_search`]
                ? comp.extend[`${f.formType}_search`]
                : comp.build,
              {
                props: {
                  field: f,
                  value: this.form[f.fieldName],
                  disableMap: true,
                  placeholder: Utils.genPlaceholder(f),
                  version: f.version,
                  setting: f.setting,
                  tree: f.tree,
                  collapseTags: f.collapseTags,
                  showAllLevels: f.showAllLevels,
                  propsV2: f.propsV2,
                },
                on: {
                  update: (event) => this.update(event)
                },
              }
            );
          }

          return h(
            "form-item",
            {
              props: {
                label: f.displayName,
                needValidate: false,
              },
            },
            [childComp]
          );
        },
      },
      render(h) {
        return (
          <div
            class={`form-item-container ${
              this.columnNum == 2 ? "two-columns" : ""
            }`}
          >
            {this.fields.map((f) => this.renderInput(h, f))}
          </div>
        );
      },
      components: {
        LabelSearch,
        ...SettingComponents
      },
    },
  },
};
</script>
<style lang="scss">
.task-search-forms {
  transition: height 0.5s;
  .form-item {
    width: 340px !important;
  }
}
</style>
<style lang="scss" scoped>
.base-panel {
  z-index: 2001;
}
.advanced-search-form {
  overflow: auto;
  padding: 10px 20px 150px 20px;

  height: calc(100%);
  justify-content: space-between;
  overflow-x: hidden;

  .two-columns {
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      width: 50%;
    }
  }

  .form-item-container {
    justify-content: space-between;
  }
  ::v-deep .base-panel-title {
    padding: 20px;
  }

  ::v-deep .form-item {
    width: auto;
    label {
      padding-left: 0;
    }
  }

  ::v-deep .advanced-search-btn-group {
    display: flex;
    justify-content: flex-end;
    // width: 100%;
    position: absolute;
    bottom: 0px;
    background: #fff;
    // padding: 15px 20px;
    padding: 15px 0;
    width: calc(100% - 40px);

    .base-button {
      margin: 0 10px;
    }
  }
}
.hide {
  overflow: hidden;
  padding: 0;
  height: 0;
  width: 0;
}
.task-search-panel-title {
  height: 54px;
  line-height: 54px;
  padding: 0 15px;
}
.task-search-guide {
  position: relative;
  left: 120px;
  margin-bottom: 20px;
  > div {
    &:first-child {
      width: 0;
      height: 0;
      border-left: 4px solid transparent;
      border-right: 4px solid transparent;
      border-bottom: 6px solid $color-primary-light-6;
      @include borderBottomColor();
      margin-left: 15px;
    }
    &:last-child {
      position: relative;
      width: 267px;
      height: 50px;
      font-size: 14px;
      color: #fff;
      line-height: 50px;
      @include backgroundColor();
      box-shadow: 0px 6px 16px 0px rgba(0, 0, 0, 0.08),
        0px 3px 6px -4px rgba(0, 0, 0, 0.12);
      text-align: center;
      border-radius: 4px;
      > span {
        font-size: 12px;
        font-family: fantasy;
        position: absolute;
        top: 8px;
        right: 9px;
        line-height: 10px;
      }
    }
  }
}
</style>

<style lang="scss">
.advanced-search-form {
  overflow: auto;
  padding: 10px 15px 63px 15px;

  height: calc(100% - 52px);
  justify-content: space-between;

  .two-columns {
    display: flex;
    flex-wrap: wrap;
    .el-form-item {
      width: 50%;
    }
  }

  .form-item-container {
    justify-content: space-between;
  }
}
</style>